import PropTypes from 'prop-types';
import { UIEventHandler, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { debounce } from '../../util/debounce';
import './virtualScroll.css';

export function VirtualScroll<T>(props:{
    itemSize: number;
    itemCount: number;
    dataList: T[];
    containerHeight: number;
    customChildren: PropTypes.ReactElementLike | string | ((data: any) => JSX.Element);
}) {
    const {itemSize, itemCount, dataList, customChildren, containerHeight} = props;
    let [clientHeight, setClientHeight] = useState(0);
    let [scrollHeight, setScrollHeight] = useState(0);
    let [scrollTop, setScrollTop] = useState(0);
    let [showList, setShowList] = useState(dataList.slice(0, Math.floor(scrollTop / itemSize)));
    let [index, setIndex] = useState(0);
    let [container, setContainer] = useState<HTMLElement | null>(null);
    const totalHeight = useMemo(() => itemSize * dataList.length, [itemSize, dataList]);
    useEffect(() => {
        setContainer(document.querySelector('.virtual-container') as HTMLElement)
    }, []);
    useEffect(() => {
        const index = Math.floor(scrollTop / itemSize);
        const count = containerHeight / itemSize;
        const list = dataList.slice(index, index + count);
        setShowList(list);
    }, [scrollTop, itemSize, dataList, containerHeight]);
    const onScroll = useCallback(debounce<any>((event: any) => {
        const scrollContainer = event.target;
        const scrollTop = scrollContainer.scrollTop;
        setClientHeight(scrollContainer.clientHeight);
        setScrollHeight(scrollContainer.scrollHeight);
        setScrollTop(scrollTop);
        const hooker = document.getElementById('hook');
        hooker!.style.transform = `translateY(${scrollTop}px)`
    }, 300), []);

    return <div id="virtual-container" className="virtual-container">
        <div className="left-view">
            <p>clientHeight: {clientHeight}</p>
            <p>scrollHeight: {scrollHeight}</p>
            <p>scrollTop: {scrollTop}</p>
        </div>
        <div onScroll={onScroll} className="right-view">
            <div className="right-scroll" style={{height: totalHeight + 'px'}}>
                <div id="hook">
                    {typeof customChildren === 'function' && showList.map(data => customChildren(data))}
                </div>
            </div>
        </div>
    </div>
}

export function TestVirtualScroll() {
    const dataList = useMemo(() => {
        const arr = [];
        for(let i = 0; i < 200; i++) {
            arr.push({
                name: `我是${i}个`,
                value: i
            })
        }
        return arr;
    }, []);
    const customChildren = useMemo(() => {
        return (data: any) => <div className="custom-item" id={"scroll-" + data.value} key={data.value}>{data.value}{data.name}</div>;
    }, []);
    return <div className="test-virtual">
        <VirtualScroll dataList={dataList} itemSize={60} itemCount={10} containerHeight={500}
            customChildren={customChildren}
        />
    </div>
}